package provider

import (
	"encoding/json"
	"fmt"
	"github.com/go-redis/redis"
	"github.com/kingwrcy/devNews/model"
	"log"
)

type RedisStorage struct {
	Storage
	Client *redis.Client
}

const redisPrefix = "devNews"
const redisUuidPrefix = "devNews:uuids"

func NewRedisStorage(addr string) RedisStorage {
	client := redis.NewClient(&redis.Options{
		Addr:     addr,
		Password: "", // no password set
		DB:       0,  // use default DB
	})
	return RedisStorage{
		Client: client,
	}
}

func (r RedisStorage) Close() {
	r.Client.Close()
}

func (r RedisStorage) Save(source string, items []model.News) bool {
	var bs []interface{}
	for _, v := range items {
		bb, err := json.Marshal(v)
		if err != nil {
			log.Printf("marshal error : %s", err)
			return false
		}

		if r.Exists(v.Uuid) {
			continue
		}

		bs = append(bs, bb)
		r.Client.SAdd(redisUuidPrefix, v.Uuid)
		log.Printf("insert into %s ,title:%s\n", source, v.Title)
	}
	fmt.Printf("bs::%v\n", len(bs))

	ret := r.Client.LPush(fmt.Sprintf("%s:%s", redisPrefix, source), bs...).Val()
	fmt.Printf("RetCode:%d\n", ret)
	return true
}

func (r RedisStorage) Exists(uuid string) bool {
	return r.Client.SIsMember(redisUuidPrefix, uuid).Val()
}

func (r RedisStorage) GetByPageSize(category string, start, offset int64) []model.News {
	var items []model.News
	ret := r.Client.LRange(fmt.Sprintf("%s:%s", redisPrefix, category), start, start+offset).Val()
	for _, v := range ret {
		item := model.News{}
		json.Unmarshal([]byte(v), &item)
		items = append(items, item)
	}
	return items
}

func (r RedisStorage) Total(category string) int {
	return int(r.Client.LLen(fmt.Sprintf("%s:%s", redisPrefix, category)).Val())
}
